use codegraph_lsp::{LspManagerConfig, LspServerConfig};

#[test]
fn test_default_config_creation() {
    let config = LspManagerConfig::default();
    
    // 检查全局设置
    assert!(config.global_settings.enable_diagnostics);
    assert!(config.global_settings.enable_completion);
    assert!(config.global_settings.enable_hover);
    assert_eq!(config.global_settings.max_completion_items, 100);
    assert_eq!(config.global_settings.diagnostic_delay_ms, 500);
    
    // 检查默认服务器配置
    assert!(config.servers.contains_key("python"));
    assert!(config.servers.contains_key("typescript"));
    assert!(config.servers.contains_key("rust"));
    assert!(config.servers.contains_key("java"));
    assert!(config.servers.contains_key("cpp"));
    assert!(config.servers.contains_key("go"));
}

#[test]
fn test_server_config_defaults() {
    let config = LspServerConfig::default();
    
    assert!(config.enabled);
    assert!(config.auto_restart);
    assert_eq!(config.max_restart_count, 3);
    assert_eq!(config.restart_interval, 5);
    assert_eq!(config.health_check_interval, 30);
    assert!(config.file_extensions.is_empty());
    assert!(config.language_ids.is_empty());
}

#[test]
fn test_python_server_config() {
    let config = LspManagerConfig::default();
    let python_config = config.servers.get("python").unwrap();
    
    assert_eq!(python_config.name, "Python Language Server");
    assert_eq!(python_config.command, "pylsp");
    assert!(python_config.args.is_empty());
    assert!(python_config.file_extensions.contains(&".py".to_string()));
    assert!(python_config.file_extensions.contains(&".pyi".to_string()));
    assert!(python_config.language_ids.contains(&"python".to_string()));
    assert!(python_config.enabled);
}

#[test]
fn test_typescript_server_config() {
    let config = LspManagerConfig::default();
    let ts_config = config.servers.get("typescript").unwrap();
    
    assert_eq!(ts_config.name, "TypeScript Language Server");
    assert_eq!(ts_config.command, "typescript-language-server");
    assert_eq!(ts_config.args, vec!["--stdio".to_string()]);
    assert!(ts_config.file_extensions.contains(&".ts".to_string()));
    assert!(ts_config.file_extensions.contains(&".tsx".to_string()));
    assert!(ts_config.file_extensions.contains(&".js".to_string()));
    assert!(ts_config.file_extensions.contains(&".jsx".to_string()));
    assert!(ts_config.language_ids.contains(&"typescript".to_string()));
    assert!(ts_config.language_ids.contains(&"javascript".to_string()));
}

#[test]
fn test_rust_server_config() {
    let config = LspManagerConfig::default();
    let rust_config = config.servers.get("rust").unwrap();
    
    assert_eq!(rust_config.name, "Rust Analyzer");
    assert_eq!(rust_config.command, "rust-analyzer");
    assert!(rust_config.args.is_empty());
    assert!(rust_config.file_extensions.contains(&".rs".to_string()));
    assert!(rust_config.language_ids.contains(&"rust".to_string()));
}

#[test]
fn test_get_server_for_extension() {
    let config = LspManagerConfig::default();
    
    // 测试Python文件
    let python_server = config.get_server_for_extension(".py");
    assert!(python_server.is_some());
    assert_eq!(python_server.unwrap().command, "pylsp");
    
    // 测试TypeScript文件
    let ts_server = config.get_server_for_extension(".ts");
    assert!(ts_server.is_some());
    assert_eq!(ts_server.unwrap().command, "typescript-language-server");
    
    // 测试Rust文件
    let rust_server = config.get_server_for_extension(".rs");
    assert!(rust_server.is_some());
    assert_eq!(rust_server.unwrap().command, "rust-analyzer");
    
    // 测试未知扩展名
    let unknown_server = config.get_server_for_extension(".unknown");
    assert!(unknown_server.is_none());
}

#[test]
fn test_get_server_for_language() {
    let config = LspManagerConfig::default();
    
    // 测试Python语言
    let python_server = config.get_server_for_language("python");
    assert!(python_server.is_some());
    assert_eq!(python_server.unwrap().command, "pylsp");
    
    // 测试TypeScript语言
    let ts_server = config.get_server_for_language("typescript");
    assert!(ts_server.is_some());
    assert_eq!(ts_server.unwrap().command, "typescript-language-server");
    
    // 测试JavaScript语言（应该返回TypeScript服务器）
    let js_server = config.get_server_for_language("javascript");
    assert!(js_server.is_some());
    assert_eq!(js_server.unwrap().command, "typescript-language-server");
    
    // 测试未知语言
    let unknown_server = config.get_server_for_language("unknown");
    assert!(unknown_server.is_none());
}

#[test]
fn test_get_enabled_servers() {
    let mut config = LspManagerConfig::default();
    
    // 默认情况下所有服务器都应该启用
    let enabled_servers = config.get_enabled_servers();
    assert_eq!(enabled_servers.len(), 6); // python, typescript, rust, java, cpp, go
    
    // 禁用Python服务器
    config.servers.get_mut("python").unwrap().enabled = false;
    let enabled_servers = config.get_enabled_servers();
    assert_eq!(enabled_servers.len(), 5);
    
    // 确保Python服务器不在启用列表中
    assert!(!enabled_servers.iter().any(|(name, _)| *name == "python"));
}

#[test]
fn test_config_serialization() {
    let config = LspManagerConfig::default();
    
    // 测试序列化
    let json_str = serde_json::to_string_pretty(&config).unwrap();
    assert!(!json_str.is_empty());
    assert!(json_str.contains("servers"));
    assert!(json_str.contains("global_settings"));
    assert!(json_str.contains("python"));
    assert!(json_str.contains("typescript"));
    
    // 测试反序列化
    let deserialized_config: LspManagerConfig = serde_json::from_str(&json_str).unwrap();
    assert_eq!(deserialized_config.servers.len(), config.servers.len());
    assert_eq!(deserialized_config.global_settings.enable_diagnostics, config.global_settings.enable_diagnostics);
}

#[test]
fn test_custom_server_config() {
    let mut config = LspManagerConfig::default();
    
    // 添加自定义服务器配置
    let custom_server = LspServerConfig {
        name: "Custom Language Server".to_string(),
        command: "custom-lsp".to_string(),
        args: vec!["--custom-arg".to_string()],
        file_extensions: vec![".custom".to_string()],
        language_ids: vec!["custom".to_string()],
        enabled: true,
        auto_restart: false,
        max_restart_count: 5,
        restart_interval: 10,
        health_check_interval: 60,
        ..Default::default()
    };
    
    config.servers.insert("custom".to_string(), custom_server);
    
    // 验证自定义配置
    let custom_config = config.servers.get("custom").unwrap();
    assert_eq!(custom_config.name, "Custom Language Server");
    assert_eq!(custom_config.command, "custom-lsp");
    assert_eq!(custom_config.args, vec!["--custom-arg".to_string()]);
    assert!(!custom_config.auto_restart);
    assert_eq!(custom_config.max_restart_count, 5);
    
    // 测试通过扩展名查找
    let found_server = config.get_server_for_extension(".custom");
    assert!(found_server.is_some());
    assert_eq!(found_server.unwrap().command, "custom-lsp");
}

#[test]
fn test_global_settings_modification() {
    let mut config = LspManagerConfig::default();
    
    // 修改全局设置
    config.global_settings.enable_diagnostics = false;
    config.global_settings.max_completion_items = 50;
    config.global_settings.diagnostic_delay_ms = 1000;
    config.global_settings.max_concurrent_servers = 5;
    
    // 验证修改
    assert!(!config.global_settings.enable_diagnostics);
    assert_eq!(config.global_settings.max_completion_items, 50);
    assert_eq!(config.global_settings.diagnostic_delay_ms, 1000);
    assert_eq!(config.global_settings.max_concurrent_servers, 5);
}

#[test]
fn test_config_file_operations() {
    use std::fs;
    use tempfile::tempdir;
    
    let config = LspManagerConfig::default();
    let temp_dir = tempdir().unwrap();
    let config_path = temp_dir.path().join("test_config.json");
    
    // 测试保存配置到文件
    let save_result = config.save_to_file(&config_path);
    assert!(save_result.is_ok());
    assert!(config_path.exists());
    
    // 测试从文件加载配置
    let loaded_config = LspManagerConfig::load_from_file(&config_path);
    assert!(loaded_config.is_ok());
    
    let loaded_config = loaded_config.unwrap();
    assert_eq!(loaded_config.servers.len(), config.servers.len());
    assert_eq!(loaded_config.global_settings.enable_diagnostics, config.global_settings.enable_diagnostics);
    
    // 清理
    fs::remove_file(&config_path).ok();
}
